<?php

use Base\AdminController;
use Illuminate\Support\Str;
use JetBrains\PhpStorm\NoReturn;
use Cache\Redis;
use Jwt\Token;

class UserController extends AdminController
{
	protected string $table = "users";

    protected string $model = "user";

    #[NoReturn] public function init(): void
    {
        $this->routeWhiteLst = [
            'user@loginlog','user@operatelog','user@logout','user@token'
        ];
        if (Request::input("title")) {
            $this->where[] = ['username','like', '%'.Request::input("title").'%'];
        }
        parent::init();
        if ($this->member_id!=1) {
            $this->where[] = ['id','<>',1];
        }
    }

    /**
     * 个人信息
     * @return void
     */
    #[NoReturn] public function infoAction(): void
    {
        try {
            $info = $this->user;
            if ($info['id']) {
                $role_ids = [];
                if ($info->role) {
                    $role_ids = $info->role->pluck("role_id")->toArray();
                    $info['roles'] = RoleModel::query()->whereIn("id",$role_ids)
                        ->get()->pluck("identify")->toArray();
                }else {
                    $info['roles'] = [];
                }
                unset($info['role']);
                $info['name'] = $info['username'];
                $info['introduction'] = '';
                $info['title'] = $info['nickname'];
                if ($this->member_id != 1) {
                    $permission_id = RoleHasPermissionModel::query()->whereIn("role_id",$role_ids)
                        ->get()->pluck("permission_id")->toArray();
                    $btn = PermissionModel::query()->where("type", 2)->whereIn("id", $permission_id)
                        ->pluck("permission_mark")->toArray();
                } else {
                    $btn = PermissionModel::query()->where("type", 2)->pluck("permission_mark")->toArray();
                }
                $info['permissions'] = $btn;
                $this->apiSuccess($info->toArray(), "获取成功", 20000);
            } else {
                $this->apiError($info);
            }
        }catch (Exception $exception) {
            $this->apiError($exception->getMessage());
        }
    }

    #[NoReturn] public function tokenAction(): void
    {
        try {
            $info = $this->user;
            if ($info['id']) {
                $uid = str_replace(['/','=','.'],"",yaf_encrypt($info['id']));
                $this->apiSuccess(["token"=>$uid], "获取成功", 20000);
            } else {
                $this->apiError($info);
            }
        }catch (Exception $exception) {
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 获取列表页数据
     * @return void
     */
    #[NoReturn] public function indexAction(): void
    {
        try {
            $sort = Request::input("sort");
            $orderBy = match ($sort)
            {
                "-id"=>'asc',
                default => 'desc',
            };
            if (Request::input("is_hid") !== null) {
                $this->where[] = ['is_hid','=',Request::input("is_hid")];
            }
            if (Request::input("title") !== null) {
                $this->where[] = ['username','like','%'.Request::input("title").'%'];
            }
			$sql = UserModel::query()->with(["role"]);
			if (Request::input("time")) {
                if (is_array(Request::input("time"))) {
                    $sql->whereBetween("created_at",Request::input("time"));
                }else {
                    $sql->whereDate("created_at",Request::input("time"));
                }
            }
            if (Request::input("org_id")&&Request::input("org_id")!=1) {
                $sql->whereHas("organization",function ($query) {
                    $query->where("organization_id",Request::input("org_id"));
                });
            }
            $data = $sql->where($this->where)
                ->orderBy("id",$orderBy)
                ->paginate(Request::input("per_page",10));
            $result = [
                'items' => collect($data->items())->toArray(),
                'total'=>$data->total(),
                'per_page' => $data->perPage(),
                'page' => $data->currentPage()
            ];
            $this->apiSuccess($result,"获取成功",20000);
        }catch (Exception $e) {
            $this->apiError($e->getMessage());
        }
    }

    /**
     * 修改个人资料
     * @return void
     */
    #[NoReturn] public function modifyAction(): void
    {
        try {
            if (!empty(Request::input("password"))) {
                $salt = get_rand_char(6);
                $password = Request::input("password");
                $data['password'] = generate_password($password,$salt);
                $data['salt'] = $salt;
            }
            $data['email'] = Request::input("email");
            $data['mobile'] = Request::input("email");
            $data['nickname'] = Request::input("nickname");
            UserModel::where("id",$this->member_id)->update($data);
            $this->apiSuccess([], "修改成功", 20000);
        }catch (Exception $exception) {
            $this->apiError($exception->getMessage());
        }
    }

    /**重置密码
     * @return void
     */
    #[NoReturn] public function resetPasswordAction(): void
    {
        try {
            if (!Request::input("ids")) $this->apiError("请选择要重置的用户");
            $salt = get_rand_char(6);
            $password = Request::input("password");
            $data['password'] = generate_password($password,$salt);
            $data['salt'] = $salt;
            UserModel::where("id",Request::input("ids"))->update($data);
            $this->apiSuccess([], "修改成功", 20000);
        }catch (Exception $exception) {
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 编辑信息
     * @return void
     */
    #[NoReturn] public function editAction():void
    {
        DB::beginTransaction();
        try {
			if (Request::instance()->isPost()||Request::instance()->isPut()) {
				if (mb_strlen(Request::input("username")) > 15) $this->apiError("用户名不能超过15个字符");
				if (mb_strlen(Request::input("nickname")) > 15) $this->apiError("用户名不能超过15个字符");
				if (mb_strlen(Request::input("mobile"))>11) $this->apiError("手机号格式不正确");
				$data = [
					'username' => Request::input("username"),
					'nickname' => Request::input("nickname"),
					'email' => Request::input("email"),
					'mobile' => Request::input("mobile"),
					'avatar' => Request::input("avatar"),
                    'position_id'=>Request::input("position_id")
				];
				if (!empty(Request::input("password"))) {
					$salt = get_rand_char(6);
					$password = Request::input("password");
					$data['password'] = generate_password($password, $salt);
					$data['salt'] = $salt;
				}
                $user = UserModel::query()->where('id',Request::input("id"))->first();
                if (!$user) $this->apiError("数据不存在");
                UserModel::where('id',Request::input("id"))->update($data);
                UserHasRoleModel::where('user_id',Request::input("id"))->delete();
                $insert = [];
                foreach (Request::input('role_id') as $vo) {
                    $insert[] = [
                        'role_id'=>$vo,
                        'user_id'=>$user['id'],
                        'type'=>'admin'
                    ];
                }
                UserHasRoleModel::insert($insert);
                Redis::getRedis()->del("backendPermissions-".$user->uuid);
                $this->userOrg($user['id']);
                DB::commit();
                $this->apiSuccess([], "修改成功", 20000);
			}else {
                $info = UserModel::query()->with(["role","organization"])->where('id',Request::input("ids"))->first();
                $info['role_id'] = $info->role->pluck('role_id');
                $info['org_id'] = $info->organization->pluck('id');
                unset($info['role'],$info['organization']);
                $this->apiSuccess( $info->toArray(),"获取成功",20000);
			}
        }catch (Exception $exception) {
            DB::rollBack();
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 添加
     * @return void
     */
    #[NoReturn] public function addAction(): void
    {
        if (Request::instance()->isPost()) {
            try {
                $params  = Request::all();
                $role_id = $params['role_id'];
                $params['uuid'] = (string)Str::uuid();
                $params['created_at'] = date("Y-m-d H:i:s");
                $salt = get_rand_char(6);
                $params['password'] = generate_password($params['password'],$salt);
                $params['salt'] = $salt;
                unset($params['role_id'],$params['org_id']);
                $params['avatar'] = makeTxtAvatar($params['uuid'],$params['nickname']);
                $params['creator_id'] = $this->member_id;
                $res = UserModel::insertGetId($params);
                $insert = [];
                foreach ($role_id as $vo) {
                    $insert[] = [
                        'role_id'=>$vo,
                        'user_id'=>$res,
                        'type'=>'admin'
                    ];
                }
                UserHasRoleModel::insert($insert);
                $info = UserModel::where('id',$res)->first();
                Redis::getRedis()->del("backendPermissions-".$info->uuid);
                $this->userOrg($info['id']);
                $this->apiSuccess( $info->toArray(),"新增成功",20000);
            }catch (Exception $exception) {
                $this->apiError($exception->getMessage());
            }
        } else {
			$this->apiError("请求类型错误");
		}
    }

    /**
     * 组织 - 用户关系处理
     * @param $userId
     * @return void
     */
    protected function userOrg($userId): void
    {
        if (Request::input("org_id")) {
            $org = [];
            foreach (Request::input("org_id") as $vo) {
                $org[] = [
                    'organization_id'=>$vo,
                    'user_id'=>$userId
                ];
            }
            OrganizationUserModel::where("user_id",$userId)->delete();
            OrganizationUserModel::insert($org);
        }
    }

    /**
     * 登录日志
     * @return void
     */
    #[NoReturn] public function loginLogAction(): void
    {
        try {
            $orderBy = match (Request::input("sort"))
            {
                "-id"=>'asc',
                default => 'desc',
            };
            $sql = LoginLogModel::query()->when(Request::input("sort"),function ($query) use($orderBy){
                $query->orderBy("id",$orderBy);
            })->where("user_id",$this->member_id);
            $data = $sql->paginate(Request::input("limit",10),['*'],NULL,Request::input("p",1));
            $result = [
                'items' => collect($data->items())->toArray(),
                'total'=>$data->total(),
                'per_page' => $data->perPage(),
                'page' => $data->currentPage()
            ];
            $this->apiSuccess($result,"获取成功",20000);
        }catch (Exception $e) {
            $this->apiError($e->getMessage());
        }
    }

    /**
     * 操作日志
     * @return void
     */
    #[NoReturn] public function operateLogAction(): void
    {
        try {
            $orderBy = match (Request::input("sort"))
            {
                "-id"=>'asc',
                default => 'desc',
            };
            $sql = OperateLogModel::query()->where($this->where)->when(Request::input("sort"),function ($query) use($orderBy){
                $query->orderBy("id",$orderBy);
            })->where("user_id",$this->member_id);
            $data = $sql->paginate(Request::input("limit",10),['*'],NULL,Request::input("p",1));
            $result = [
                'items' => collect($data->items())->toArray(),
                'total'=>$data->total(),
                'per_page' => $data->perPage(),
                'page' => $data->currentPage()
            ];
            $this->apiSuccess($result,"获取成功",20000);
        }catch (Exception $exception) {
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }

    /**
     * 退出登录
     * @return void
     */
    #[NoReturn] public function logoutAction():void
    {
        try {
            Redis::getRedis()->del("backendPermissions-" . $this->user['uuid'],
                Token::$prefix_refresh.$this->member_id,
                Token::$prefix_member.$this->member_id);
            $this->apiSuccess([],"退出成功",20000);
        } catch (RedisException $exception) {
            Log::$customFileName = LOG_PATH."/errors/";
            Log::error($exception->getMessage().$exception->getTraceAsString());
            $this->apiError($exception->getMessage());
        }
    }
}
